package at.jku.pervasive;

import java.awt.Color;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;

import org.jibx.runtime.BindingDirectory;
import org.jibx.runtime.IBindingFactory;
import org.jibx.runtime.IMarshallingContext;
import org.jibx.runtime.IUnmarshallingContext;
import org.jibx.runtime.JiBXException;

public final class Helper
{

	private static final Color[] colors;
	private static final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd, HH:mm");
	public static final String LINE_SEPARATOR = System.getProperty("line.separator");
	private static final IMarshallingContext marshallingContext;
	private static final Random random = new Random();
	private static final IUnmarshallingContext unmarshallingContext;

	static
	{
		colors = new Color[] { Color.RED, Color.BLUE, Color.GREEN };

		try
		{
			IBindingFactory bindingFactory = BindingDirectory.getFactory(Measurement.class);
			unmarshallingContext = bindingFactory.createUnmarshallingContext();
			marshallingContext = bindingFactory.createMarshallingContext();
		} catch (JiBXException e)
		{
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}

	public static Date deserializeTimestampDate(String dateString)
	{
		long timeInMillis = Long.parseLong(dateString);
		return new Date(timeInMillis);
	}

	public static final String formatDate(Date date)
	{
		if (date == null)
			return null;

		return dateFormat.format(date);
	}

	public static Date getDateMillisecondsAgo(long milliseconds)
	{
		return new Date(now().getTime() - milliseconds);
	}

	public static Color getRandomColor()
	{
		int index = (int) (random.nextDouble() * colors.length);
		return colors[index];
	}

	public static boolean isOlderThan(Date timestamp, long timeDelta)
	{
		return timeDiff(timestamp.getTime()) > timeDelta;
	}

	public static Date now()
	{
		return new Date();
	}

	public static Measurement readMeasurementSeries(InputStream inStream)
	{
		try
		{
			return (Measurement) unmarshallingContext.unmarshalDocument(inStream, null);
		} catch (JiBXException e)
		{
			e.printStackTrace();
		}
		return null;
	}

	public static String serializeTimestampDate(Date date)
	{
		if (date != null)
			return Long.toString(date.getTime());

		return "";
	}

	public static long timeDiff(long time)
	{
		return now().getTime() - time;
	}

	public static void writeMeasurement(Measurement measurement, File measurementFile)
	{
		try
		{
			OutputStream out = new FileOutputStream(measurementFile);
			marshallingContext.setOutput(out, null);
			marshallingContext.setIndent(4);
			marshallingContext.startDocument("UTF-8", null);
			marshallingContext.marshalDocument(measurement);
			marshallingContext.endDocument();
		} catch (JiBXException e)
		{
			e.printStackTrace();
		} catch (FileNotFoundException e)
		{
			e.printStackTrace();
		}
	}

}
